﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System.Globalization;

namespace EpsiRisk.DonneesPlateau
{
    [XmlType]
    public class ClassPlateau
    {
        /// <summary>
        /// nom du plateau de jeu
        /// </summary>
        [XmlAttribute]
        public string Nom;

        /// <summary>
        /// nom du fichier  de fond de carte
        /// </summary>
        [XmlAttribute]
        public string FondCarte;

        /// <summary>
        /// sprite dans lequel charger le fond
        /// </summary>
        [XmlIgnore]
        public Texture2D spriteFondCarte;

        /// <summary>
        /// taille de la carte(en pixels)
        /// </summary>
        [XmlElement]
        public Vector2 TailleCarte;

        /// <summary>
        /// nom des territoires
        /// </summary>
        [XmlAttribute]
        public string AliasTerritoire = "Territoire";

        /// <summary>
        /// nom des sous territoires
        /// </summary>
        [XmlAttribute]
        public string AliasSousTerritoire = "Sous-Territoire";

        /// <summary>
        /// liste des territoires du plateau
        /// </summary>
        [XmlElement("Territoire")]
        public List<ClassTerritoire> ListeTerritoires = new List<ClassTerritoire> { };

        /// <summary>
        /// sauvegarde du plateau vers un fichier XML
        /// </summary>
        public void sauvegardePlateau()
        {
            XmlSerializer serializer = new XmlSerializer(this.GetType());
            TextWriter textWriter = new StreamWriter("Plateau" + DateTime.Today.ToString("d", new CultureInfo("de-DE")) + ".xml");
            serializer.Serialize(textWriter, this);
            textWriter.Close();
        }


        //propriété exposant les voisinages  pour serialiser/deserialiser sans references circulaires
        [XmlArray]
        public List<ClassVoisinage> Voisinages
        {
            get
            {
                List<ClassVoisinage> voisinages = new List<ClassVoisinage> { };
                foreach (ClassTerritoire t in ListeTerritoires)
                {
                    foreach (ClassSousTerritoire st in t.ListeSousTerritoire)
                    {
                        foreach (ClassSousTerritoire v in st.Voisins)
                        {
                            if (!voisinages.Contains(new ClassVoisinage(v, st))) //verifie que le lien de voisinage n'est pas déjà présent
                            {
                                ClassVoisinage vois = new ClassVoisinage(st, v);

                                voisinages.Add(vois);
                            }

                        }
                    }
                }
                return voisinages;
            }
            set
            {
                //voisinages = value;
                foreach (ClassVoisinage v in value)
                {
                    foreach (ClassTerritoire t in ListeTerritoires)
                    {
                        foreach (ClassSousTerritoire st in t.ListeSousTerritoire)
                        {
                            if (st == v.voisin1)
                            {
                                if (!st.Voisins.Contains(v.voisin2))
                                {
                                    st.Voisins.Add(v.voisin2);
                                }
                            }
                            if (st == v.voisin2)
                            {
                                if (!st.Voisins.Contains(v.voisin1))
                                {
                                    st.Voisins.Add(v.voisin1);
                                }
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// rends l'ensemble des sous-territoires contenus sur le plateau
        /// </summary>
        /// <returns></returns>
        public List<ClassSousTerritoire> listeSousTerritoires()
        {
            List<ClassSousTerritoire> l = new List<ClassSousTerritoire> { };
            foreach (ClassTerritoire t in ListeTerritoires)
            {
                l.AddRange(t.ListeSousTerritoire);
            }
            return l;
        }

        public ClassSousTerritoire rechercheSousTerritoireParNom(string nom)
        {
            foreach (ClassSousTerritoire st in listeSousTerritoires())
            {
                if (st.Nom == nom)
                {
                    return st;
                }
            }

            Console.WriteLine("Sous-territoire correspondant à : " + nom + " non trouvé !");
            return null;
        }

        /// <summary>
        /// import d'un plateau depuis un fichier XML
        /// </summary>
        /// <returns></returns>
        public ClassPlateau chargementPlateau(string filename)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(ClassPlateau));
            XmlTextReader textReader = new XmlTextReader(filename);
            ClassPlateau sortie = (ClassPlateau)serializer.Deserialize(textReader);
            textReader.Close();
            return sortie;
        }

        /// <summary>
        /// charge les sprites correspondant au plateau
        /// </summary>
        internal void loadSprites(ContentManager content)
        {
            spriteFondCarte = content.Load<Texture2D>("Plateaux//" + FondCarte);
            // chargement recursif des sprite de territoires & sous territoires
            foreach (ClassSousTerritoire st in listeSousTerritoires())
            {
                try
                {
                    st.calque = content.Load<Texture2D>("Plateaux/SurbrillancePays2/" + st.Nom);
                }
                catch 
                {
                    Console.WriteLine("Calque du sous territoire "+st.Nom+" non chargé");
                }
            }
            
        }

        public ClassTerritoire getContinent(ClassSousTerritoire sT)
        {
            ClassTerritoire terre = new ClassTerritoire();
            foreach (ClassTerritoire T in  ListeTerritoires)
            {
                if (T.ListeSousTerritoire.Contains(sT))
                    terre = T;
            }
            return terre;
        }

        /// <summary>
        /// nombre de territoires possédes par un joueur
        /// </summary>
        /// <param name="j">Joueur dont on souhaite connaitre le nombre de territoires</param>
        /// <returns></returns>
        public int nombreSousTerritoiresPossedes(ClassJoueur j)
        {
            int res = 0;
            foreach (ClassSousTerritoire st in listeSousTerritoires())
            {
                if (st.Proprietaire == j)
                {
                    res++;
                }
            }
            return res;
        }


        internal void viderSoldats()
        {
            foreach (ClassSousTerritoire st in listeSousTerritoires())
            {
                while (st.nbArmees != 0)
                {
                    st.enleverSoldat();
                }
            }
        }
    }
}
